/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package exatrez.manager;

import com.google.inject.Inject;
import com.wideplay.warp.persist.Transactional;
import exatrez.dao.ShipVisitCrewDAO;
import exatrez.dao.ShipVisitDescriptionDAO;
import exatrez.dao.ShipVisitFlowCounterDAO;
import exatrez.dao.ShipVisitFlowDAO;
import exatrez.dao.ShipVisitFlowFileDAO;
import exatrez.dao.ShipVisitFlowFileTmpDAO;
import exatrez.dao.ShipVisitFlowHistoryDAO;
import exatrez.dao.ShipVisitHeaderDAO;
import exatrez.model.ShipVisitCrew;
import exatrez.model.ShipVisitDescription;
import exatrez.model.ShipVisitFlow;
import exatrez.model.ShipVisitFlowCounter;
import exatrez.model.ShipVisitFlowFile;
import exatrez.model.ShipVisitFlowFileTmp;
import exatrez.model.ShipVisitFlowHistory;
import exatrez.model.User;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Query;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author Admin
 */
public class ShipVisitFlowManager {
    
    @Inject
    private ShipVisitFlowCounterDAO shipVisitFlowCounterDAO;
    @Inject
    private ShipVisitFlowDAO shipVisitFlowDAO;
    @Inject
    private ShipVisitFlowFileTmpDAO shipVisitFlowFileTmpDAO;
    @Inject
    private ShipVisitFlowFileDAO shipVisitFlowFileDAO;
    @Inject
    private ShipVisitCrewDAO shipVisitCrewDAO;
    @Inject
    private ShipVisitDescriptionDAO shipVisitDescDAO;
    @Inject
    private ShipVisitHeaderDAO shipVisitHeadDAO;
    @Inject
    private ShipVisitFlowHistoryDAO historyDAO;
    
    private static String SUCCESS = "success";
    private static String FAIL = "fail";
    
    @Inject
    protected com.google.inject.Provider<Session> sessionProvider;
    
    private static Logger LOG = LoggerFactory.getLogger(ShipVisitFlowManager.class);
    
    public List<ShipVisitFlowCounter> getListCounter(User user, String year, String departmentId){
        StringBuilder sb = new StringBuilder("select s from ShipVisitFlowCounter s, User u ")
                .append("where s.user = u ");
        
        Session session = sessionProvider.get();
        
        if(user != null){
            sb.append("and s.user.userId = :userId ");
        }
        if(year != null){
            sb.append("and s.year = :year ");
        }
        if(departmentId != null){
            sb.append("and u.department.departmentId = :departmentId ");
        }
        sb.append("order by s.infoAudit.createDate");
        
        Query query = session.createQuery(sb.toString());
        if(user != null){
            query.setParameter("userId", user.getUserId());
        }
        if(year != null){
            query.setParameter("year", year);
        }
        if(departmentId != null){
            query.setParameter("departmentId", Integer.parseInt(departmentId));
        }
        return query.list();
    }
    
    @Transactional
    public String saveOrUpdateVisitCounter(ShipVisitFlowCounter visitCounter){
        String result = SUCCESS;
        LOG.info("ShipVisitFlowCounter.Id :"+visitCounter.getSvFlowCounterId());
        try{
            shipVisitFlowCounterDAO.saveOrUpdate(visitCounter);
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace();//for development use only
            result = FAIL;
        }
        return result;
    }
    
    @Transactional
    public String saveOrUpdateVisit(ShipVisitFlow svFlow){
        String result = SUCCESS;
        try{
            shipVisitFlowDAO.saveOrUpdate(svFlow);
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace();//for development use only
            result = FAIL;
        }
        return result;
    }
    
    @Transactional
    public void saveHistory(ShipVisitFlowHistory history){
        try{
            historyDAO.save(history);
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace();//for development use only
        }
    }
    
    @Transactional
    public String saveOrUpdateVisit(ShipVisitFlow svFlow, List<ShipVisitFlowFileTmp> listFileTmp){
        String result = SUCCESS;
        try{
            shipVisitFlowDAO.saveOrUpdate(svFlow);
            for (ShipVisitFlowFileTmp fileTmp : listFileTmp) {
                ShipVisitFlowFile file = new ShipVisitFlowFile();
                file.setContentType(fileTmp.getContentType());
                file.setShipVisitFlow(svFlow);
                file.setDeleted(fileTmp.getDeleted());
                file.setDocumentPath(fileTmp.getDocumentPath());
                file.setTitle(fileTmp.getTitle());
                file.setInfoAudit(fileTmp.getInfoAudit());
                shipVisitFlowFileDAO.saveOrUpdate(file);
                shipVisitFlowFileTmpDAO.delete(fileTmp);
            }
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace();//for development use only
            result = FAIL;
        }
        return result;
    }
    
    public List<ShipVisitFlow> getListVisitKIV(User user, String year){
        StringBuilder sb = new StringBuilder("select s from ShipVisitFlow s ")
                .append("where s.user.userId  = :userId and s.deleted = 'N' and s.status = 'K' ");
        if(StringUtils.isNotBlank(year)){
            sb.append("and year(s.dateVisit) = :year ");
        }
        sb.append("order by s.infoAudit.createDate desc");
        
        Session session = sessionProvider.get();
        
        Query query = session.createQuery(sb.toString()).setParameter("userId", user.getUserId());
        if(StringUtils.isNotBlank(year)){
            query.setInteger("year", Integer.parseInt(year));
        }
        
        return query.list();
    }
    
    public List<ShipVisitFlow> getListVisitApproved(User user, String year){
        StringBuilder sb = new StringBuilder("select s from ShipVisitFlow s ")
                .append("where s.user.userId  = :userId and s.deleted = 'N' and s.status = 'A' ");
        if(StringUtils.isNotBlank(year)){
            sb.append("and year(s.dateVisit) = :year ");
        }
        sb.append("order by s.infoAudit.createDate desc");
        
        Session session = sessionProvider.get();
        
        Query query = session.createQuery(sb.toString()).setParameter("userId", user.getUserId());
        if(StringUtils.isNotBlank(year)){
            query.setInteger("year", Integer.parseInt(year));
        }
        
        return query.list();
    }
    
    public List<ShipVisitFlow> getListVisitRejected(User user, String year){
//        String year = String.valueOf(new Date().getYear()+1900);
//        System.out.println("getListVisitRejected : year : "+year);
        StringBuilder sb = new StringBuilder("select s from ShipVisitFlow s ")
                .append("where s.user.userId  = :userId and s.deleted = 'N' and s.status = 'R' ");
        if(StringUtils.isNotBlank(year)){
            sb.append("and year(s.dateVisit) = :year ");
        }
        sb.append("order by s.infoAudit.createDate desc");
        
        Session session = sessionProvider.get();
        
        Query query = session.createQuery(sb.toString()).setParameter("userId", user.getUserId());
        if(StringUtils.isNotBlank(year)){
            query.setInteger("year", Integer.parseInt(year));
        }
        
        return query.list();
    }
    
    public List<ShipVisitFlow> getAllListStaffVisitKIV(){
        StringBuilder sb = new StringBuilder("select s from ShipVisitFlow s ")
                .append("where s.deleted = 'N' and s.status = 'K' order by s.infoAudit.createDate desc");
        
        Session session = sessionProvider.get();
        
        Query query = session.createQuery(sb.toString());
        
        return query.list();
    }
    
    public List<ShipVisitFlowFileTmp> getListFiletmp(String staffId){
        StringBuilder sb = new StringBuilder("select s from ShipVisitFlowFileTmp s ")
                .append("where s.deleted = 'N' and s.user.userId = :userId");
        
        Session session = sessionProvider.get();
        
        Query query = session.createQuery(sb.toString()).setParameter("userId", staffId);
        
        return query.list();
    }
    
    @Transactional
    public String saveorUpdateVisitFiletmp(ShipVisitFlowFileTmp visitFiletmp){
        String result = SUCCESS;
        try{
            shipVisitFlowFileTmpDAO.saveOrUpdate(visitFiletmp);
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace(); //for development use only
            result = FAIL;
        }
        return result;
    }
    
    @Transactional
    public String saveorUpdateVisitFile(ShipVisitFlowFile visitFile){
        String result = SUCCESS;
        try{
            shipVisitFlowFileDAO.saveOrUpdate(visitFile);
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace(); //for development use only
            result = FAIL;
        }
        return result;
    }
    
    public List<ShipVisitDescription> listShipVisitDescription(){
        StringBuilder sb = new StringBuilder("select s from ShipVisitDescription s ")
                .append("order by s.sortNumber asc");
        
        Session session = sessionProvider.get();
        
        Query query = session.createQuery(sb.toString());
        
        return query.list();
    }
    
    @Transactional
    public String updateAndSaveCrew(ShipVisitFlow svf, List<ShipVisitCrew> listSvc){
        String result = SUCCESS;
        try{
            shipVisitFlowDAO.saveOrUpdate(svf);
            for (ShipVisitCrew shipVisitCrew : listSvc) {
                shipVisitCrewDAO.saveOrUpdate(shipVisitCrew);
            }
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace(); //for development use only
            result = FAIL;
        }
        return result;
    }
    
    public List<ShipVisitCrew> listCrew(String headerId, String svFlowId){
        StringBuilder sb = new StringBuilder("select c from ShipVisitCrew c, ShipVisitDescription d ")
                .append("where c.shipVisitFlowId.shipVisitFlowId = :fid ")
                .append("and c.svDescId.svDescId = d.svDescId ");
                if(headerId != null){
                    sb.append("and d.svHeaderId.svHeaderId = :hid ");
                }                
                sb.append("order by d.sortNumber asc");
        
        Session session = sessionProvider.get();
        
        Query query = session.createQuery(sb.toString()).setInteger("fid", Integer.parseInt(svFlowId));
                if(headerId != null){
                    query.setString("hid", headerId);
                }
                
        return query.list();
    }
    
    public List<ShipVisitFlow> listApproveReject(String userId, String status, String year){
        StringBuilder sb = new StringBuilder("select s from ShipVisitFlow s ")
                .append("where s.user.userId = :uid ")
                .append("and s.deleted = 'N' ")
                .append("and s.status = :status ")
                .append("and year(s.dateVisit) = :year ")
                .append("order by s.infoAudit.createDate desc ");
        
        Session session = sessionProvider.get();
        
        Query query = session.createQuery(sb.toString()).setParameter("uid", userId).setString("status", status).setInteger("year", Integer.parseInt(year));
        
        return query.list();
    }
    
    @Transactional
    public String saveorUpdateSVDesc(ShipVisitDescription svDesc){
        String result = SUCCESS;
        try{
            shipVisitDescDAO.saveOrUpdate(svDesc);
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace(); //for development use only
            result = FAIL;
        }
        return result;
    }
    
    @Transactional
    public String deleteSVDesc(ShipVisitDescription svDesc){
        String result = SUCCESS;
        try{
            shipVisitDescDAO.delete(svDesc);
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace(); //for development use only
            result = FAIL;
        }
        return result;
    }
    
    public List<ShipVisitFlowHistory> listHistory(String svfId){
        StringBuilder sb = new StringBuilder("select s from ShipVisitFlowHistory s ")
                .append("where s.shipVisitFlow.shipVisitFlowId = :svfid ")
                .append("order by s.infoAudit.createDate asc ");
        
        Session session = sessionProvider.get();
        
        Query query = session.createQuery(sb.toString()).setInteger("svfid", Integer.parseInt(svfId));
        
        return query.list();
    }
    
    @Transactional
    public String saveCrew(ShipVisitCrew svc){
        String result = SUCCESS;
        try{
            shipVisitCrewDAO.saveOrUpdate(svc);
        }catch(Exception ex){
            ex.printStackTrace(); // for development used only
            LOG.error(ex.getMessage());
            result = FAIL;
        }
        return result;
    }
    
}
